import logging
import os.path

logger = logging.getLogger(__name__)

def _invalidate_top_fileset(graph, fset):
  visited = set()
  if fset.is_output():
    _invalidate_genrule(graph, visited, fset.gen_rule)
  _invalidate_fileset(graph, visited, fset)

def _invalidate_fileset(graph, visited, fset):
  if fset in visited: return
  visited.add(fset)
  logger.debug("invalidating: " + str(fset.key)) 
  if fset.is_wipe():
    graph.try_delete_gen_rule_with_key(fset.key.genrule_key)
  else:
    if fset.is_input():
      _invalidate_genrule(graph, visited, fset.gen_rule)
    for fset in fset.reverse_dependencies:
      _invalidate_fileset(graph, visited, fset)

def _invalidate_genrule(graph, visited, rule):
  if rule in visited: return
  visited.add(rule)
  if not rule.valid:
    return
  rule.set_valid(False)
  logger.debug("invalidating: " + str(rule)) 
  for fset in rule.out.getFsets():
    if len(fset.files) != 0:
      _invalidate_fileset(graph, visited, fset)

def _is_build_file(fname):
  return os.path.basename(fname) == "BUILD"

def invalidate_file_list(graph, flist):
  """Invalidates all of the files in a list.

  Args:
    graph: The dep_graph.cache.FileBackedCachedGraph to invalidate files in.
    flist: The set of files to invalidate.
  """
  deleted = set()
  for fname in flist:
    if _is_build_file(fname):
      print("Reloading", fname)
      deleted.update(graph.delete_build_file(fname))
    elif fname not in deleted:
      for fset in graph.get_fsets_for_file(fname):
        _invalidate_top_fileset(graph, fset)
